--
-- Author: mm
-- Date: 2018-08-06 15:45:19
--
-- NewerbattleguideView
-- 新手战引导UI

local Armature = app:getClass("Armature")
local NewerBattleGuideTipsRender = import(".renders.NewerBattleGuideTipsRender")

local fileName = string.getModeName(...)
local ClassRef = class(fileName, app.mvc.ViewBase)

ClassRef.VIEW_ROOT_RES = Res.newerBattleGuideDialogNode

local string_split = string.split
local string_find = string.find

local guideEndType =
{
    dialogEnd = 1, -- 对话结束
    funcEnd = 2, -- 功能按钮点击结束
    dialogEndStartNext = 3, -- 对话结束并立即触发下一个引导
}

function ClassRef:init()
	self._ui.Panel:setVisible( false )

	-- 底层屏蔽UI
	self._bgLayer = display.newColorLayer( cc.c4b( 0,0,0,0 ) )
	self._bgLayer:setContentSize( display.width, display.height )
	self._bgLayer:setTouchEnabled( true )
	self:addChild( self._bgLayer, -1 )

	-- 移动控制特效
	self._rockerEffect = cc.CSLoader:createNode( Res.newerBattleGuideRocker, true, true )
	self._rockerEffect:setVisible( false )
	self:addChild( self._rockerEffect )

	-- 技能特效
	self._skillEffect = cc.CSLoader:createNode( Res.newerBattleGuideSkill, true, true )
	self._skillEffect:setVisible( false )
	self:addChild( self._skillEffect )

	-- 移动指引特效
	self._moveEffect = cc.CSLoader:createNode( Res.newerBattleGuideArrow, true, true )
	self._moveEffect:setVisible( false )
	self._moveEffect:setPosition( cc.p( display.width - 75, display.height/2 ) )
	self:addChild( self._moveEffect )

	-- 上层响应点击节点
	self._clickLayer = display.newLayer()
	self._clickLayer:setContentSize( cc.size( 0, 0 ) )
	display.nodeTouchOneByOne( self._clickLayer,
		function( posX, posY )
			if self._clickLayer:hitTest(posX,posY) then
				self:onClick()
			end
		end )
	self._clickLayer:setTouchEnabled( true )
	self._clickLayer:setSwallowsTouches( false )
	self:addChild( self._clickLayer, 9999 )

	-- 上层响应点击跳过对话节点
	self._clickLayerSkipDialog = display.newLayer()
	self._clickLayerSkipDialog:setContentSize( cc.size( display.width, display.height ) )
	display.nodeTouchOneByOne( self._clickLayerSkipDialog,
		function( posX, posY )
			if self._clickLayerSkipDialog:hitTest(posX,posY) then
				self:onClickSkipDialog()
			end
		end )
	self._clickLayerSkipDialog:setTouchEnabled( true )
	self._clickLayerSkipDialog:setSwallowsTouches( false )
	self:addChild( self._clickLayerSkipDialog, 9998 )

	-- 跳过按钮
	self._ui.btn_tg:setVisible(true)
	self._ui.btn_tg:addClickEventListener(function()
		self:stopAction(self._actionGuideEnd)
		executeFunc(self._onOperate, "skipGuide")
	end)

	self:setBackGroundColorOpacity(0)
	display.setCascadeOpacityEnabled(self._root, true)
end

function ClassRef:onClick()
	local endPar = self._guideConf.endPar
	local parList = string_split(endPar, "|")
	local uiType = tonumber(parList[1])
	local node
	if 1 == uiType then -- 桌面主UI
		if string_find(parList[2], "rocker") then
			self._rockerEffect:setVisible(false)
			self:_hideHandArmature()
		end
	end
	-- TODO: 硬编码
	-- 第二步(引导移动)不在操作之后立即归还提层的节点
	-- 因为此时的整个desktop不可见
	-- 控制移动控件延迟到触发战斗时归还
	if 3 ~= tonumber( self._guideConf.guideIdx ) then
		executeFunc(self._onOperate, "curGuideGoing")
		if self._guideConf.endSkillId == nil then
			self:nodeReturn()
			executeFunc( self._onOperate, "curGuideEnd" )
		end
	end
end

function ClassRef:onClickSkipDialog()
	if self._guideConf and self._guideConf.textContent and self._flagSkipDialog == false
	  and self._dialogRefreshGuideIndex == app:getInst("NewerbattleguideController"):getNextGuideIndex() then
		local textProtectTime = tonumber(self._guideConf.textProtectTime) or 0
		if textProtectTime > 0 then -- 存在文本保护时间？
			if app:getTime() - self._dialogRefreshTime <= textProtectTime then
				return
			end
		end

		self._ui.text:stopAction(self._actionHideText)
		self._ui.Panel:setVisible(false)
		local endType = tonumber(self._guideConf.endType)
		if guideEndType.dialogEnd == endType then -- 对话完成作为结束条件？
			self:stopAction(self._actionGuideEnd)
			executeFunc(self._onOperate, "curGuideGoing")
			executeFunc(self._onOperate, "curGuideEnd")
		elseif guideEndType.dialogEndStartNext == endType then
			self:stopAction(self._actionGuideEnd)
			executeFunc(self._onOperate, "curGuideGoing")
			executeFunc(self._onOperate, "curGuideEndAndtriggerBattleGuide")
		end
		self._flagSkipDialog = true
	end
end

-- 刷新引导数据
function ClassRef:refresh(guideConf)
	if guideConf then
		self:show()
		self._guideConf = guideConf
		self:_refreshDialog()

		local textProtectTime = tonumber(self._guideConf.textProtectTime) or 0
		if textProtectTime > 0 then -- 存在文本保护时间？
			self:performWithDelay(handler(self, self._adjustGuideNode), textProtectTime)
		else
			self:_adjustGuideNode()
		end
	else
		printError("Newer battle guide configure data is nil!")
	end
end

-- 刷新对话框内容
function ClassRef:_refreshDialog()
	local role = tonumber(self._guideConf.textRole)
	self._dialogRefreshGuideIndex = tonumber(self._guideConf.guideIdx)
	if role then
		local panel
		if role == 1 then
			self._ui.Panel_left:setVisible(true)
			self._ui.Panel_right:setVisible(false)
			panel = self._ui.Panel_left
		elseif role == 2 then
			self._ui.Panel_left:setVisible(false)
			self._ui.Panel_right:setVisible(true)
			panel = self._ui.Panel_right
		end
		if self._guideConf.textTitle then
			panel:findChild("name"):setString(L(self._guideConf.textTitle))
		end

		if self._guideConf.textContent then -- 对话有内容
			self._ui.Panel:setVisible(true)
			self._ui.text:setString(L(self._guideConf.textContent))
			self._flagSkipDialog = false
			self._dialogRefreshTime = app:getTime()
		else
			self._flagSkipDialog = true
			self._ui.Panel:setVisible(false)
		end
	else
		self._flagSkipDialog = true
		self._ui.Panel:setVisible(false)
	end

	local remainTime = tonumber(self._guideConf.textRemainTime)
	if remainTime > 0 then -- 存在显示时间？
		self._actionHideText = self._ui.text:performWithDelay(function()
			self._ui.Panel:setVisible(false)
			self._flagSkipDialog = true
		end, remainTime-0.25)
		local endType = tonumber(self._guideConf.endType)
		if guideEndType.dialogEnd == endType then -- 对话完成作为结束条件？
			self._actionGuideEnd = self:performWithDelay(function()
				self._flagSkipDialog = true
				executeFunc(self._onOperate, "curGuideGoing")
				executeFunc(self._onOperate, "curGuideEnd")
			end, remainTime)
		elseif guideEndType.dialogEndStartNext == endType then
			self._actionGuideEnd = self:performWithDelay(function()
				self._flagSkipDialog = true
				executeFunc(self._onOperate, "curGuideGoing")
				executeFunc(self._onOperate, "curGuideEndAndtriggerBattleGuide")
			end, remainTime)
		end
	end
end

-- 帮助函数：打印节点列表
-- local function printNodeList( node )
-- 	if 0 >= node:getChildrenCount() then
-- 		print( " -------------->>>>>> ", node:getName() )
-- 	else
-- 		for k,v in pairs( node:getChildren() ) do
-- 			printNodeList( v )
-- 		end
-- 	end
-- end

-- 引导Node提层
function ClassRef:_adjustGuideNode()
	local endType = tonumber(self._guideConf.endType)
	local endPar = self._guideConf.endPar
	if guideEndType.funcEnd ~= endType or "" == endPar then
		return
	end
	local idx = string_find(endPar, "|")
	if not idx then
		print( " ---------->>>>>>>>>> funcEnd参数error " )
		return
	end

	print( " ---------->>>>>>>>>> 提高节点 ", string.sub(endPar, idx+1))
	local parList = string_split(endPar, "|")
	local uiType = tonumber(parList[1])
	local node
	local nodePosXY
	if 1 == uiType then -- 桌面主UI
		local desktopUiNode = UIHandler:getDesktopController():getDesktop():getUiNode()
		node = desktopUiNode:findChild( parList[2] )
		if string_find(parList[2], "rocker") then
			nodePosXY = cc.p(node:findChild( "radius" ):getPosition())
			self._rockerEffect:setPosition(nodePosXY.x + display.safe_x, nodePosXY.y)
			--self._rockerEffect:setPosition(node:findChild( "radius" ):getPosition())
			self._rockerEffect:setVisible( true )
			self._moveEffect:setVisible( true )
		end
	elseif 2 == uiType then -- 战斗技能面板
		-- 技能出现
		local battleSkillPanel = BattleManager.mBattleController.mNewBattleUIView.bottomView.skillPanelView
		battleSkillPanel:showSkillBtnName(parList[2])
		node = battleSkillPanel:findChild( parList[2] )
		if string_find( parList[2], "skill" ) then -- 普攻
			node = node:getChildByName("Panel")
		end
		if string_find(parList[2], "skill") or string_find(parList[2], "attack") then
			self._skillEffect:setVisible( true )
		end
	elseif 3 == uiType then -- 战斗移动面板
		local controller = BattleManager.mBattleController.mNewBattleUIView.controller
		node = controller:findChild( parList[2] )
		nodePosXY = cc.p(node:getPosition()) 
		self._rockerEffect:setPosition(nodePosXY.x + display.safe_x, nodePosXY.y)
		--self._rockerEffect:setPosition(node:getPosition())
		self._rockerEffect:setVisible( true )
	end

	if not node then
		print( " ------------->>>>>>> 找不到节点" )
		return
	end

	local parent = node:getParent()
	local pos = cc.p(node:getPosition())
	local zorder = node:getLocalZOrder()
	local anchorPoint = node:getAnchorPoint()

	local worldPos = parent:convertToWorldSpace(pos)
	node:retain()
	node:removeFromParent(false)
	self:addChild( node, 9998 )
	node:setPosition(worldPos)
	node:release()

	-- 调整响应区尺寸、位置
	local nodeWidth, nodeHeight = node:getContentSize2()
	self._clickLayer:setContentSize( cc.size( nodeWidth, nodeHeight ) )
	local posX = worldPos.x - nodeWidth*anchorPoint.x
	local posY = worldPos.y - nodeHeight*anchorPoint.y
	self._clickLayer:setPosition( cc.p( posX, posY ) )

	-- 调整战斗UI指导动画位置
	self._skillEffect:setPosition( worldPos )
	self._skillEffect:setScale( nodeWidth/110 )

	self._node = node
	self._parent = parent
	self._pos = pos
	self._zorder = zorder

	self:_playHandArmature()
end

-- node归还给原parent
function ClassRef:nodeReturn()
	if self._node == nil then
		return
	end
	if not cc.isDead( self._node ) and
		not cc.isDead( self._parent ) then
		print( " ---------->>>>>>>>>> 归还节点 " )
		local node = self._node
		node:retain()
		node:removeFromParent(false)
		self._parent:addChild(node)
		node:setPosition( self._pos )
		self._parent:reorderChild( node, self._zorder )
		node:release()
	end
	self._node = nil
	self._parent = nil
	self._clickLayer:setContentSize( cc.size( 0, 0 ) )
	self:_hideHandArmature()
	self._rockerEffect:setVisible( false )
	self._moveEffect:setVisible( false )
end

-- 显示手动画和提示文字
function ClassRef:_playHandArmature()
	local armature = self._handArmature
	local conf = Res.GuideFinger
	if not armature then
		local params = {
			armatureName = conf.name,
			path = conf.dir
		}
		armature = Armature.create(params)
		self:addChild(armature, 10000)
		self._handArmature = armature
	end

	local boundingBox = self._clickLayer:getBoundingBox()
	local posX = boundingBox.x + boundingBox.width/2
	local posY = boundingBox.y + boundingBox.height/2
	armature:setPosition( cc.p( posX, posY ) )
	armature:setVisible(true)
	armature:play(conf.action)

	if self._guideConf.tipsContent then
		-- 手指点击处的提示信息有内容
		local tips = self._tips
	    if not self._tips then
			tips = NewerBattleGuideTipsRender.create()
			self:addChild(tips)
			self._tips = tips
		end
		tips:setPosition(cc.p(posX, posY))
		tips:refresh(L(self._guideConf.tipsContent))
		tips:show()
	end
end

-- 隐藏手动画和提示文字
function ClassRef:_hideHandArmature()
	if self._handArmature then
		self._handArmature:stop()
		self._handArmature:setVisible(false)
	end
	if self._tips then
		self._tips:hide()
	end
end

-- 播放镜头动画
function ClassRef:playCameraZoomAction()
	MapManager:getMap():setZoomScale(2)
	self._bgLayer:setOpacity(255)
	self._bgLayer:runAction(cc.Sequence:create(cc.DelayTime:create(0), cc.FadeOut:create(1)))

	self._actionZoomCamera = self:performWithDelay(function()
		MapManager:forceCameraZoomToDest({dstScale = 0.7,time = 1,call = function()
			executeFunc(self._onOperate, "cameraActionEnd")
		end})
	end, 0)
end

-- 当前步骤引导结束的清理工作
function ClassRef:curGuideEndClear()
	if self._actionHideText then
		self._ui.text:stopAction(self._actionHideText)
		self._actionHideText = nil
	end
	if self._actionGuideEnd then
		self:stopAction(self._actionGuideEnd)
		self._actionGuideEnd = nil
	end
	if self._actionZoomCamera then
		self:stopAction(self._actionZoomCamera)
		self._actionZoomCamera = nil
	end

	self._ui.Panel:setVisible( false )
	self._rockerEffect:setVisible( false )
	self._skillEffect:setVisible( false )

	-- 第二步(引导移动)不在操作之后立即归还提层的节点
	-- 因为整个desktop不可见，控制移动控件延迟到触发战斗时归还
	-- 不隐藏自身也是这个原因，移动控件要保留
	-- 保留到 self:triggerNewerBattle 调用处处理
	if self._guideConf then
		local curIdx = tonumber( self._guideConf.guideIdx )
		if 2 ~= curIdx then
			self._moveEffect:setVisible( false )

			-- 此处添加特殊逻辑：3~6持续显示响应遮罩层。
			-- 避免玩家操作影响引导流程
			if 3 <= curIdx and curIdx <= 6 then
				self:setVisible( true )
			else
				self:setVisible( false )
			end
		end
	end
end

-- 触发新手战
-- TODO: 硬编码 之前步骤提层的控件(移动控制控件)延迟到此处归还
function ClassRef:triggerNewerBattle()
	if self._guideConf and 3 == tonumber( self._guideConf.guideIdx ) then
		executeFunc(self._onOperate, "curGuideGoing")
		self:nodeReturn()
		executeFunc( self._onOperate, "curGuideEnd" )
	else
		executeFunc(self._onOperate, "skipGuide")
	end
end

-- 新手战结束boss爆炸特效
function ClassRef:playGuideEndAni()
	self:show()

	self._ui.Panel:setVisible( false )
	self._rockerEffect:setVisible( false )
	self._skillEffect:setVisible( false )
	self._moveEffect:setVisible( false )

	if not self._bossDeadAni then
		local params = {
			path = Res.newerBattleGuideBossBomb.dir,
			armatureName = Res.newerBattleGuideBossBomb.name,
		}
		self._bossDeadAni = Armature.create( params )
		self:addChild( self._bossDeadAni )
		self._bossDeadAni:setPosition( cc.p( display.width/2, display.height/2 ) )
	end
	self._bossDeadAni:play( "release", 1, function()
		executeFunc( self._onOperate, "curGuideGoing" )
		executeFunc( self._onOperate, "curGuideEnd" )
	end )
end

return ClassRef
